﻿using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
using DevExpress.LookAndFeel;
using DevExpress.Utils;
using DevExpress.Utils.Drawing;
using DevExpress.XtraEditors.Controls;
using DevExpress.Skins;
using System.Collections.Generic;
using System.Text;
using XtraTaskDialog.Resources;
using DevExpress.XtraEditors.Repository;
using System.Threading;

namespace DevExpress.XtraEditors
{
    public static class XtraTaskDialog
    {

        static DialogResult[] MessageBoxButtonsToDialogResults(MessageBoxButtons buttons)
        {
            if (!Enum.IsDefined(typeof(MessageBoxButtons), buttons))
            {
                throw new InvalidEnumArgumentException("buttons", (int)buttons, typeof(DialogResult));
            }
            switch (buttons)
            {
                case MessageBoxButtons.OK:
                    return new DialogResult[] { DialogResult.OK };
                case MessageBoxButtons.OKCancel:
                    return new DialogResult[] { DialogResult.OK, DialogResult.Cancel };
                case MessageBoxButtons.AbortRetryIgnore:
                    return new DialogResult[] { DialogResult.Abort, DialogResult.Retry, DialogResult.Ignore };
                case MessageBoxButtons.RetryCancel:
                    return new DialogResult[] { DialogResult.Retry, DialogResult.Cancel };
                case MessageBoxButtons.YesNo:
                    return new DialogResult[] { DialogResult.Yes, DialogResult.No };
                case MessageBoxButtons.YesNoCancel:
                    return new DialogResult[] { DialogResult.Yes, DialogResult.No, DialogResult.Cancel };
                default:
                    throw new ArgumentException("buttons");
            }
        }

        static Icon MessageBoxIconToIcon(MessageBoxIcon icon)
        {
            if (!Enum.IsDefined(typeof(MessageBoxIcon), icon))
            {
                throw new InvalidEnumArgumentException("icon", (int)icon, typeof(DialogResult));
            }
            switch (icon)
            {
                case MessageBoxIcon.None:
                    return null;
                case MessageBoxIcon.Error:
                    return SystemIcons.Error;
                case MessageBoxIcon.Exclamation:
                    return SystemIcons.Exclamation;
                case MessageBoxIcon.Information:
                    return SystemIcons.Information;
                case MessageBoxIcon.Question:
                    return SystemIcons.Question;
                default:
                    throw new ArgumentException("icon");
            }
        }

        static int MessageBoxDefaultButtonToInt(MessageBoxDefaultButton defButton)
        {
            if (!Enum.IsDefined(typeof(MessageBoxDefaultButton), defButton))
            {
                throw new InvalidEnumArgumentException("defaultButton", (int)defButton, typeof(DialogResult));
            }
            switch (defButton)
            {
                case MessageBoxDefaultButton.Button1:
                    return 0;
                case MessageBoxDefaultButton.Button2:
                    return 1;
                case MessageBoxDefaultButton.Button3:
                    return 2;
                default:
                    throw new ArgumentException("defaultButton");
            }
        }

        public static DialogResult Show(IWin32Window owner, string Title, string MainInstruction, string Content, MessageBoxButtons Buttons, MessageBoxIcon Icon)
        {
            return Show(null, owner, Title, MainInstruction, Content, Buttons, Icon);
        }

        public static DialogResult Show(UserLookAndFeel lookAndFeel, IWin32Window owner, string Title, string MainInstruction, string Content, MessageBoxButtons Buttons, MessageBoxIcon Icon)
        {
            MessageBeep((int)Icon);
            bool VerificationChecked;
            int SelectedCustomButton;
            int SelectedRadioButton;
            return Show(
                new XtraTaskDialogArgs(
                    lookAndFeel,
                    owner,
                    Title,
                    MainInstruction,
                    Content,
                    MessageBoxButtonsToDialogResults(Buttons),
                    MessageBoxIconToIcon(Icon).ToBitmap(),
                    -1),
                out SelectedCustomButton,
                out SelectedRadioButton,
                out VerificationChecked);
        }

        public static DialogResult Show(XtraTaskDialogArgs Options, out int SelectedCustomButton, out int SelectedRadioButton, out bool VerificationChecked)
        {
            XtraTaskDialogForm form = new XtraTaskDialogForm();
            DialogResult result = form.ShowMessageBoxDialog(Options);
            VerificationChecked = form.VerificationChecked;
            SelectedCustomButton = form.SelectedCustomButton;
            SelectedRadioButton = form.SelectedRadioButton;
            return result;
        }

        public static DialogResult Show(XtraTaskDialogArgs Options)
        {
            int opt;
            bool opt1;
            return Show(Options, out opt, out opt, out opt1);
        }

        #region API
        [DllImport("user32.dll")]
        static extern bool MessageBeep(int uType);
        #endregion

        static bool _AllowCustomLookAndFeel = false;
        public static bool AllowCustomLookAndFeel
        {
            get { return _AllowCustomLookAndFeel; }
            set { _AllowCustomLookAndFeel = value; }
        }
    }

    [Flags]
    public enum XtraTaskDialogFlags
    {
        None = 0,
        ShowProgressBar = 1,
        ShowMarqueeProgressBar = 2,
        UseCallbackTimer = 4,
        EnableHyperlinks = 8
    }

    public enum XtraTaskDialogNotificationType
    {
        None = 0,
        Timer = 1,
        Created = 2,
        HyperlinkClicked = 4
    }

    public delegate void XtraTaskDialogNotificationDelegate(
        XtraTaskDialogForm Window,
        XtraTaskDialogNotificationType NotificationType,
        object Data);

    public class XtraTaskDialogArgs
    {
        int defaultRadioButton = -1;

        public XtraTaskDialogArgs() : this(null, string.Empty, string.Empty, string.Empty, new DialogResult[0], null, 0) { }

        public XtraTaskDialogArgs(IWin32Window owner, string Title, string MainInstruction, string Content, DialogResult[] buttons, Image icon, int defaultButtonIndex) :
            this(null, owner, Title, MainInstruction, Content, buttons, icon, defaultButtonIndex) { }

        public XtraTaskDialogArgs(UserLookAndFeel lookAndFeel, IWin32Window owner, string Title, string MainInstruction, string Content, DialogResult[] buttons, Image icon, int defaultButtonIndex)
        {
            this.LookAndFeel = lookAndFeel;
            this.Owner = owner;
            this.MainInstruction = MainInstruction;
            this.Title = Title;
            this.Content = Content;
            this.Buttons = buttons;
            this.Icon = icon;
            this.DefaultButtonIndex = defaultButtonIndex;
        }

        public UserLookAndFeel LookAndFeel { get; set; }

        public UserLookAndFeel GetLookAndFeel()
        {
            if (LookAndFeel != null)
            {
                return LookAndFeel;
            }

            XtraForm form = Owner as XtraForm;
            if (form != null)
            {
                return form.LookAndFeel;
            }

            return null;
        }

        public Image Icon { get; set; }

        public string Title { get; set; }

        public string MainInstruction { get; set; }

        public int DefaultButtonIndex { get; set; }

        public IWin32Window Owner { get; set; }

        public DialogResult[] Buttons { get; set; }

        public string Content { get; set; }

        public string ExpandedInfo { get; set; }

        public string VerificationText { get; set; }

        public XtraTaskDialogButton[] CustomButtons { get; set; }

        public bool UseCommandLinks { get; set; }

        public string FooterText { get; set; }

        public Image FooterIcon { get; set; }

        public XtraTaskDialogButton[] RadioButtons { get; set; }

        public int DefaultRadioButton
        {
            get { return defaultRadioButton; }
            set { defaultRadioButton = value; }
        }

        public XtraTaskDialogFlags Flags { get; set; }

        public XtraTaskDialogNotificationDelegate NotificationDelegate { get; set; }

        public string CustomProgressBarText { get; set; }

        /// <summary>
        /// Specifies the timeout after which to close the dialog automatically. Value should be in milliseconds and 
        /// a multiple of 1000. If the value is below 1000ms it is ignored. The countdown is shown on the button specified
        /// by the DefaultButtonIndex parameter
        /// </summary>
        public int DialogTimeout { get; set; }
    }

    public class XtraTaskDialogButton
    {

        public XtraTaskDialogButton(DialogResult Result, string Caption)
        {
            this.Result = Result;
            this.Caption = Caption;
        }

        public DialogResult Result { get; set; }
        public string Caption { get; set; }
    }

    public class XtraTaskDialogForm : XtraForm
    {
        const int Spacing = 8;
        int PanelHeight = 40;

        XtraTaskDialogArgs message;
        SimpleButton[] buttons;
        SimpleButton[] customButtons;
        int selectedCustomButton;
        Rectangle iconRectangle;
        Rectangle mainInstructionRectangle;
        LinkLabelControl content;
        LinkLabelControl expandedInfo;
        XtraScrollableControl xscTextControls;
        LinkLabelControl footerControl;
        Rectangle footerIconRectangle;

        Color _BackColor;
        AppearanceObject _page;
        Font _MainInstructionFont;
        Brush _MainInstructionBrush;

        bool _ShowExpandedInfo = false;
        SimpleButton _ShowExpandedInfoButton;
        Dictionary<bool, string> _ShowExpandedInfoText;

        CheckEdit _VerificationControl;
        RadioGroup _RadioButtons;
        ProgressBarBaseControl _ProgressBar;

        System.Threading.Timer _CallbackTimer;
        System.Threading.Timer _TimeoutTimer;
        int _CurrentTick = 0;
        int _MaxTicks;

        Control _PrevActiveControl = null;

        public XtraTaskDialogForm()
        {
            this.KeyPreview = true;
            this.message = new XtraTaskDialogArgs();
            this.MinimumSize = new System.Drawing.Size(512, 0);

            _MainInstructionBrush = new SolidBrush(Color.FromArgb(0, 51, 153));
            _MainInstructionFont = new System.Drawing.Font(DevExpress.Utils.AppearanceObject.DefaultFont.FontFamily, 12);

            //Needed for painting
            _BackColor = LookAndFeelHelper.GetSystemColor(DevExpress.LookAndFeel.UserLookAndFeel.Default, SystemColors.Window);
            _page = new AppearanceObject(new AppearanceDefault(_BackColor));

            _ShowExpandedInfoText = new Dictionary<bool, string>(2) 
            { 
                { false, XtraTaskDialogResources.ShowDetailsText },
                { true, XtraTaskDialogResources.HideDetailsText } 
            };
        }

        protected internal XtraTaskDialogArgs Message
        {
            get { return message; }
            set { message = value; }
        }

        DevExpress.Accessibility.BaseAccessible dxAccessible;
        protected internal virtual DevExpress.Accessibility.BaseAccessible DXAccessible
        {
            get
            {
                //if (dxAccessible == null) dxAccessible = new DevExpress.Accessibility.MessageBoxAccessible(this);
                return dxAccessible;
            }
        }

        protected internal AccessibleObject GetParentAccessible()
        {
            return base.CreateAccessibilityInstance().Parent;
        }

        protected override AccessibleObject CreateAccessibilityInstance()
        {
            if (DXAccessible == null) return base.CreateAccessibilityInstance();
            return DXAccessible.Accessible;
        }

        protected override bool AllowSkinForEmptyText
        {
            get { return true; }
        }

        protected virtual string GetButtonText(DialogResult target)
        {
            switch (target)
            {
                case DialogResult.Abort:
                    return Localizer.Active.GetLocalizedString(StringId.XtraMessageBoxAbortButtonText);
                case DialogResult.Cancel:
                    return Localizer.Active.GetLocalizedString(StringId.XtraMessageBoxCancelButtonText);
                case DialogResult.Ignore:
                    return Localizer.Active.GetLocalizedString(StringId.XtraMessageBoxIgnoreButtonText);
                case DialogResult.No:
                    return Localizer.Active.GetLocalizedString(StringId.XtraMessageBoxNoButtonText);
                case DialogResult.OK:
                    return Localizer.Active.GetLocalizedString(StringId.XtraMessageBoxOkButtonText);
                case DialogResult.Retry:
                    return Localizer.Active.GetLocalizedString(StringId.XtraMessageBoxRetryButtonText);
                case DialogResult.Yes:
                    return Localizer.Active.GetLocalizedString(StringId.XtraMessageBoxYesButtonText);
                default:
                    return '&' + target.ToString();
            }
        }

        public DialogResult ShowMessageBoxDialog(XtraTaskDialogArgs message)
        {
            this.message = message;
            return ShowMessageBoxDialog();
        }

        Size GetBordersSizes()
        {
            if (IsCustomPainter)
            {
                DevExpress.Skins.SkinPaddingEdges margins = FormPainter.Margins;
                return new Size(margins.Left + margins.Right, margins.Top + margins.Bottom);
            }
            else
            {
                return new Size(2 * SystemInformation.FixedFrameBorderSize.Width, 2 * SystemInformation.FixedFrameBorderSize.Height + SystemInformation.CaptionHeight);
            }
        }

        void _ShowExpandedInfoButton_Click(object sender, EventArgs e)
        {
            _ShowExpandedInfo = !_ShowExpandedInfo;
            _ShowExpandedInfoButton.Text = _ShowExpandedInfoText[_ShowExpandedInfo];

            //Change the width
            _ShowExpandedInfoButton.Width = (_ShowExpandedInfoButton.CalcBestSize().Width > _ShowExpandedInfoButton.Width ?
                        _ShowExpandedInfoButton.CalcBestSize().Width : _ShowExpandedInfoButton.Width);

            BuildTaskDialogForm(-1, false);
            this.Invalidate();
        }

        Font GetCaptionFont()
        {
            if (IsCustomPainter)
            {
                return (Font)new AppearanceObject(FormPainter.GetDefaultAppearance()).Font.Clone();
            }
            else
            {
                return ControlUtils.GetCaptionFont();
            }
        }

        int GetCloseButtonWidth()
        {
            if (IsCustomPainter)
            {
                return new DevExpress.Skins.XtraForm.FormCaptionButtonSkinPainter(FormPainter).CalcObjectMinBounds(new DevExpress.Skins.XtraForm.FormCaptionButton(DevExpress.Skins.XtraForm.FormCaptionButtonKind.Close)).Width;
            }
            else
            {
                return SystemInformation.CaptionButtonSize.Width;
            }
        }

        protected virtual bool AllowCustomLookAndFeel
        {
            get { return XtraTaskDialog.AllowCustomLookAndFeel; }
        }

        DialogResult ShowMessageBoxDialog()
        {
            if (Message.GetLookAndFeel() != null)
                LookAndFeel.Assign(Message.GetLookAndFeel());
            if (!AllowCustomLookAndFeel)
            {
                if (LookAndFeel.ActiveStyle != ActiveLookAndFeelStyle.Skin)
                {
                    ActiveLookAndFeelStyle active = UserLookAndFeel.Default.ActiveStyle;
                    if (active == ActiveLookAndFeelStyle.Office2003)
                    {
                        LookAndFeel.SetStyle(LookAndFeelStyle.Office2003, true, false, "");
                    }
                    else
                        LookAndFeel.SetDefaultStyle();
                }
            }
            this.Text = Message.Title;
            FormBorderStyle = FormBorderStyle.FixedDialog;
            MinimizeBox = false;
            MaximizeBox = false;
            IWin32Window owner = Message.Owner;
            if (owner == null)
            {
                Form activeForm = Form.ActiveForm;
                if (activeForm != null && !activeForm.InvokeRequired)
                {
                    owner = activeForm;
                }
            }
            if (owner != null)
            {
                Control ownerControl = owner as Control;
                if (ownerControl != null)
                {
                    if (!ownerControl.Visible)
                    {
                        owner = null;
                    }
                    else
                    {
                        Form ownerForm = ownerControl.FindForm();
                        if (ownerForm != null && ownerForm.IsMdiChild)
                        {
                            ownerForm = ownerForm.MdiParent;
                        }
                        if (ownerForm != null)
                        {
                            if ((!ownerForm.Visible)
                                || ownerForm.WindowState == FormWindowState.Minimized
                                || ownerForm.Right <= 0
                                || ownerForm.Bottom <= 0)
                            {
                                owner = null;
                            }
                        }
                    }
                }
            }
            if (owner == null)
            {
                ShowInTaskbar = true;
                StartPosition = FormStartPosition.CenterScreen;
            }
            else
            {
                ShowInTaskbar = false;
                StartPosition = FormStartPosition.CenterParent;
            }

            BuildTaskDialogForm();

            if (Message.NotificationDelegate != null)
            {
                Message.NotificationDelegate(this, XtraTaskDialogNotificationType.Created, null);
            }

            //Create timer
            if (Message.Flags.HasFlag(XtraTaskDialogFlags.UseCallbackTimer))
            {
                _CallbackTimer = new System.Threading.Timer(
                    new System.Threading.TimerCallback(_CallbackTimer_Tick),
                    null, 200, 200);
            }

            //Create the timeout timer if the timeout is more then 1000 ms
            if (message.DialogTimeout >= 1000 && _TimeoutTimer == null) 
            {
                //Determine max ticks
                _MaxTicks = message.DialogTimeout / 1000;
                _CurrentTick = 0;
                UpdateButtonText();

                _TimeoutTimer = new System.Threading.Timer(
                    new System.Threading.TimerCallback(_TimeoutTimer_Tick), 
                    null, 1000, 1000);  
            }

            Form frm = owner as Form;
            if (frm != null && frm.TopMost) this.TopMost = true;
            return DoShowDialog(owner);
        }

        void _CallbackTimer_Tick(object state)
        {
            if (Message.NotificationDelegate != null)
            {
                Message.NotificationDelegate(this, XtraTaskDialogNotificationType.Timer, null);
            }
        }

        protected override void OnShown(EventArgs e)
        {
            base.OnShown(e);

            if (this.ActiveControl != null)
            {
                this.ActiveControl.Select();
            }
        }

        void _TimeoutTimer_Tick(object state) 
        {
            if (_CurrentTick < _MaxTicks)
            {
                //Update button text
                UpdateButtonText();
                _CurrentTick++;
            }
            else
            {
                if (buttons == null || message.DefaultButtonIndex > buttons.Length)
                {
                    _TimeoutTimer.Change(Timeout.Infinite, Timeout.Infinite);
                    return;
                }

                //Close the dialog using the dialog result of the default button
                this.CloseDialog(message.Buttons[message.DefaultButtonIndex]);
            }
        }

        private void UpdateButtonText()
        {
            if (buttons == null || message.DefaultButtonIndex > buttons.Length)
            {
                return;
            }

            this.BeginInvoke(new MethodInvoker(delegate
            {
                buttons[message.DefaultButtonIndex].Text = string.Format("{0} ({1})",
                    GetButtonText(message.Buttons[message.DefaultButtonIndex]), _MaxTicks - _CurrentTick);
                this.Invalidate(new Rectangle(
                    buttons[message.DefaultButtonIndex].Location, 
                    buttons[message.DefaultButtonIndex].Size));
            }));
        }

        public void SetProgressBarPosition(int NewPosition)
        {
            if (!Message.Flags.HasFlag(XtraTaskDialogFlags.ShowProgressBar))
            {
                throw new ArgumentException("ProgressBar not enabled!");
            }
            else if (Message.Flags.HasFlag(XtraTaskDialogFlags.ShowMarqueeProgressBar))
            {
                throw new ArgumentException("Cannot set position on MarqueeProgressBar");
            }
            else if (((ProgressBarControl)_ProgressBar).Properties.Minimum <= NewPosition &&
                ((ProgressBarControl)_ProgressBar).Properties.Maximum >= NewPosition)
            {
                if (InvokeRequired)
                {
                    BeginInvoke(new MethodInvoker(delegate()
                    {
                        ((ProgressBarControl)_ProgressBar).Position = NewPosition;
                    }));
                }
            }
        }

        protected virtual DialogResult DoShowDialog(IWin32Window owner)
        {
            DialogResult result = ShowDialog(owner);
            this.Dispose();

            return result;
        }

        AppearanceObject GetPaintAppearance()
        {
            AppearanceObject paintAppearance = new AppearanceObject(Appearance, DefaultAppearance);
            paintAppearance.TextOptions.WordWrap = WordWrap.Wrap;
            paintAppearance.TextOptions.VAlignment = VertAlignment.Top;
            paintAppearance.TextOptions.Trimming = Trimming.EllipsisCharacter;
            return paintAppearance;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            using (GraphicsCache gcache = new GraphicsCache(e))
            {
                int top = ClientRectangle.Height - PanelHeight;
                int width = ClientRectangle.Width;

                //First paint the background 
                Rectangle rect = new Rectangle(0, 0, width, top);
                _page.FillRectangle(gcache, rect);

                //AppearanceObject.ControlAppearance.DrawBackground(cache, new Rectangle(0, top, width, height));
                SkinElementInfo info = new SkinElementInfo(
                    CommonSkins.GetSkin(DevExpress.LookAndFeel.UserLookAndFeel.Default)[CommonSkins.SkinGroupPanelNoBorder],
                    new Rectangle(0, top, width, PanelHeight));
                ObjectPainter.DrawObject(gcache, SkinElementPainter.Default, info);

                SkinElement skinLabelLine = CommonSkins.GetSkin(DevExpress.LookAndFeel.UserLookAndFeel.Default)[CommonSkins.SkinLabelLine];
                info = new SkinElementInfo(
                    skinLabelLine,
                    new Rectangle(0, top, width, skinLabelLine.Size.MinSize.Height));
                ObjectPainter.DrawObject(gcache, SkinElementPainter.Default, info);

                if (Message.FooterIcon != null || !string.IsNullOrEmpty(Message.FooterText))
                {
                    //Add a footer separator
                    if (Message.FooterIcon != null && footerControl != null)
                    {
                        if (footerIconRectangle.Top < footerControl.Top)
                        {
                            top = footerIconRectangle.Top - Spacing;
                        }
                        else
                        {
                            top = footerControl.Top - Spacing;
                        }
                    }
                    else if (Message.FooterIcon != null)
                    {
                        top = footerIconRectangle.Top - Spacing;
                    }
                    else if (footerControl != null)
                    {
                        top = footerControl.Top - Spacing;
                    }

                    info = new SkinElementInfo(
                        skinLabelLine,
                        new Rectangle(0, top, width, skinLabelLine.Size.MinSize.Height));
                    ObjectPainter.DrawObject(gcache, SkinElementPainter.Default, info);

                    if (Message.FooterIcon != null)
                    {
                        gcache.Graphics.DrawImage(Message.FooterIcon, footerIconRectangle);
                    }
                }

                //Draw the icon
                if (Message.Icon != null)
                {
                    gcache.Graphics.DrawImage(Message.Icon, this.iconRectangle);
                }

                //Draw main instruction
                GetPaintAppearance().DrawString(gcache, Message.MainInstruction, this.mainInstructionRectangle, _MainInstructionFont, _MainInstructionBrush, new StringFormat());
            }
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            if (this.CancelButton == null && this.DialogResult == DialogResult.Cancel)
                e.Cancel = true;

            //Stop timers
            if (_CallbackTimer != null)
            {
                _CallbackTimer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
            }

            if (_TimeoutTimer != null)
            {
                _TimeoutTimer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
            }

            base.OnClosing(e);
        }

        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            if (e.KeyChar == '\x03')
            {
                e.Handled = true;
                StringBuilder retValue = new StringBuilder();

                retValue.AppendFormat("[{0}]{1}", XtraTaskDialogResources.CopyWindowTitle, Environment.NewLine);
                retValue.AppendLine(Message.Title);
                retValue.AppendLine(string.Empty);

                if (!string.IsNullOrWhiteSpace(Message.MainInstruction))
                {
                    retValue.AppendFormat("[{0}]{1}", XtraTaskDialogResources.CopyMainInstruction, Environment.NewLine);
                    retValue.AppendLine(Message.MainInstruction);
                    retValue.AppendLine(string.Empty);
                }

                if (!string.IsNullOrWhiteSpace(Message.Content))
                {
                    retValue.AppendFormat("[{0}]{1}", XtraTaskDialogResources.CopyContent, Environment.NewLine);
                    retValue.AppendLine(message.Content);
                    retValue.AppendLine(string.Empty);
                }

                if (!string.IsNullOrWhiteSpace(Message.ExpandedInfo))
                {
                    retValue.AppendFormat("[{0}]{1}", XtraTaskDialogResources.CopyExpandedInfo, Environment.NewLine);
                    retValue.AppendLine(message.ExpandedInfo);
                    retValue.AppendLine(string.Empty);
                }

                if (Message.CustomButtons != null && Message.UseCommandLinks)
                {
                    retValue.AppendFormat("[{0}]{1}", XtraTaskDialogResources.CopyCommandLinks, Environment.NewLine);
                    foreach (XtraTaskDialogButton button in Message.CustomButtons)
                    {
                        retValue.AppendLine(button.Caption);
                    }
                    retValue.AppendLine(string.Empty);
                }

                bool AddEmptyLine = false;
                if (!string.IsNullOrWhiteSpace(Message.ExpandedInfo))
                {
                    retValue.AppendFormat("[{0}] {1} ", (_ShowExpandedInfo ? "^" : "V"), _ShowExpandedInfoButton.Text);
                    AddEmptyLine = true;
                }

                if (!string.IsNullOrWhiteSpace(Message.VerificationText))
                {
                    retValue.AppendFormat("[{0}] {1} ", (VerificationChecked ? "X" : " "), Message.VerificationText);
                    AddEmptyLine = true;
                }

                if (Message.CustomButtons != null && !Message.UseCommandLinks)
                {
                    foreach (XtraTaskDialogButton button in Message.CustomButtons)
                    {
                        retValue.AppendFormat("[{0}] ", button.Caption);
                        AddEmptyLine = true;
                    }
                }

                if (buttons != null)
                {
                    foreach (SimpleButton button in buttons)
                    {
                        retValue.AppendFormat("[{0}] ", button.Text);
                        AddEmptyLine = true;
                    }
                }

                if (AddEmptyLine)
                {
                    retValue.Append("\r\n");
                    retValue.AppendLine(string.Empty);
                }

                if (!string.IsNullOrWhiteSpace(Message.FooterText))
                {
                    retValue.AppendFormat("[{0}]{1}", XtraTaskDialogResources.CopyFooter, Environment.NewLine);
                    retValue.AppendLine(Message.FooterText);
                }

                Clipboard.SetDataObject(retValue.ToString(), true);
            }
        }

        protected override void OnVisibleChanged(EventArgs e)
        {
            base.OnVisibleChanged(e);
            if (this.Visible && !this.ContainsFocus)
                this.Activate();
        }

        protected internal bool VerificationChecked
        {
            get
            {
                if (_VerificationControl != null)
                {
                    return _VerificationControl.Checked;
                }

                return false;
            }
        }

        protected internal int SelectedCustomButton
        {
            get { return selectedCustomButton; }
        }

        protected internal int SelectedRadioButton
        {
            get
            {
                return (_RadioButtons == null ? -1 : _RadioButtons.SelectedIndex);
            }
        }

        private void BuildTaskDialogForm(int TextHeight = -1, bool IsFirstShown = true)
        {
            //Start top left corner and work right then down
            int FormTop, FormWidth, MaxTextWidth, TextLeft, BottomControlsHeight = 0, TopControlsHeight = 0;

            //Keep a width of 512 pixels for now
            FormWidth = 512;
            FormTop = Spacing;
            TopControlsHeight = Spacing;

            //This is the maximum width of a text item
            MaxTextWidth = FormWidth - (Spacing * 2) - GetBordersSizes().Width;
            TextLeft = Spacing;

            #region Header controls start here

            //Show the main icon?
            if (Message.Icon != null)
            {
                this.iconRectangle = new Rectangle(Spacing, Spacing, Message.Icon.Width, Message.Icon.Height);
                //Adjust the maxtextwidth and textleft for the icon size
                MaxTextWidth -= (Message.Icon.Width + Spacing);
                TextLeft += (Message.Icon.Width + Spacing);
            }
            else
            {
                this.iconRectangle = new Rectangle(Spacing, Spacing, 0, 0);
            }

            GraphicsInfo ginfo = new GraphicsInfo();
            ginfo.AddGraphics(null);

            //Calculate the MainInstruction rectangle
            mainInstructionRectangle = GetTextRectangle(
                ginfo,
                Message.MainInstruction,
                _MainInstructionFont,
                TextLeft,
                Spacing,
                MaxTextWidth - iconRectangle.Width);

            //Adjust the FormTop for the Icon or MainInstruction height
            int MainIconHeight = 0;
            if (iconRectangle.Height > mainInstructionRectangle.Height)
            {
                MainIconHeight = iconRectangle.Height;
            }
            else
            {
                MainIconHeight = mainInstructionRectangle.Height;
            }

            FormTop += MainIconHeight + Spacing;
            TopControlsHeight += MainIconHeight + Spacing;

            #endregion

            #region Content controls start here

            //Create a XtraScrollableControl to hold the text controls and have a scrollbar available
            if (xscTextControls == null)
            {
                xscTextControls = new XtraScrollableControl();
                xscTextControls.Width = MaxTextWidth;
                xscTextControls.TabStop = false;
                xscTextControls.BackColor = _BackColor;
            }

            if (TextHeight == -1)
            {
                xscTextControls.Height = 10;
            }
            else
            {
                xscTextControls.Height = TextHeight;
            }
            
            xscTextControls.Location = new Point(TextLeft, FormTop);
            this.Controls.Add(xscTextControls);

            //Create a link label for the content
            if (content == null)
            {
                content = CreateLinkLabel(Message.Content, MaxTextWidth);
                content.Location = new Point(0, 0);
                xscTextControls.Controls.Add(content);
            }

            if (content != null && TextHeight == -1)
            {
                xscTextControls.Height = content.Height;
            }

            //Calculate the expanded info rectangle
            if (!string.IsNullOrEmpty(Message.ExpandedInfo) &&
                expandedInfo == null)
            {
                expandedInfo = CreateLinkLabel(Message.ExpandedInfo, MaxTextWidth);
                if (content == null)
                {
                    expandedInfo.Location = new Point(0, 0);
                }
                else
                {
                    expandedInfo.Location = new Point(0, content.Height + Spacing);
                }
                xscTextControls.Controls.Add(expandedInfo);
            }

            //Adjust FormTop
            if (expandedInfo != null && _ShowExpandedInfo)
            {
                expandedInfo.Visible = true;
                if (TextHeight == -1)
                {
                    xscTextControls.Height += (expandedInfo.Height + Spacing);
                }
            }
            else if (expandedInfo != null && !_ShowExpandedInfo)
            {
                expandedInfo.Visible = false;
            }

            //Check if we need to adjust for the scrollbarwidth
            int TextControlsHeight = 0;
            if (content != null) 
            {
                TextControlsHeight += content.Height;
            }
            if (expandedInfo != null && _ShowExpandedInfo) 
            {
                TextControlsHeight += expandedInfo.Height;
            }

            if (xscTextControls.Height < (TextControlsHeight))
            {
                if (content != null)
                {
                    content.Width = xscTextControls.Width - SystemInformation.VerticalScrollBarWidth;
                }
                if (expandedInfo != null)
                {
                    expandedInfo.Width = xscTextControls.Width - SystemInformation.VerticalScrollBarWidth;
                }
            }

            //Adjust FormTop
            FormTop += xscTextControls.Height + Spacing;
            BottomControlsHeight += Spacing;

            //Create progress bar
            if (Message.Flags.HasFlag(XtraTaskDialogFlags.ShowMarqueeProgressBar) && _ProgressBar == null)
            {
                _ProgressBar = new MarqueeProgressBarControl();
                this.Controls.Add(_ProgressBar);
            }
            else if (Message.Flags.HasFlag(XtraTaskDialogFlags.ShowProgressBar) && _ProgressBar == null)
            {
                _ProgressBar = new ProgressBarControl();
                this.Controls.Add(_ProgressBar);
            }

            if (_ProgressBar != null && !string.IsNullOrWhiteSpace(Message.CustomProgressBarText))
            {
                ((RepositoryItemBaseProgressBar)_ProgressBar.Properties).ShowTitle = true;
                if (_ProgressBar is ProgressBarControl)
                {
                    ((ProgressBarControl)_ProgressBar).Properties.PercentView = false;
                }
                _ProgressBar.CustomDisplayText += new CustomDisplayTextEventHandler(_ProgressBar_CustomDisplayText);
            }

            //Set location of progress bar
            if (_ProgressBar != null)
            {
                _ProgressBar.Size = new System.Drawing.Size(MaxTextWidth, _ProgressBar.Size.Height);
                _ProgressBar.Location = new Point(TextLeft, FormTop);

                int prbHeight = _ProgressBar.Height + Spacing;
                FormTop += prbHeight;
                BottomControlsHeight += prbHeight;
            }

            //Create radio buttons
            if (_RadioButtons == null && (Message.RadioButtons != null && Message.RadioButtons.Length > 0))
            {
                _RadioButtons = new RadioGroup();
                _RadioButtons.BorderStyle = BorderStyles.NoBorder;
                _RadioButtons.Properties.Columns = 1;
                for (int i = 0; i < Message.RadioButtons.Length; i++)
                {
                    _RadioButtons.Properties.Items.Add(new RadioGroupItem(i, Message.RadioButtons[i].Caption));
                }

                Size bestSize = _RadioButtons.CalcBestSize();
                _RadioButtons.Size = new Size(MaxTextWidth, bestSize.Height);
                if (Message.DefaultRadioButton == -1 || Message.DefaultRadioButton > Message.RadioButtons.Length)
                {
                    _RadioButtons.SelectedIndex = 0;
                }
                else
                {
                    _RadioButtons.SelectedIndex = Message.DefaultRadioButton;
                }
                this.Controls.Add(_RadioButtons);
            }

            //Adjust location of radio buttons
            if (_RadioButtons != null)
            {
                _RadioButtons.Location = new Point(TextLeft, FormTop);
                int rdbHeight = _RadioButtons.Height + Spacing;
                FormTop += rdbHeight;
                BottomControlsHeight += rdbHeight;
            }

            //Create custom buttons (command or push buttons)
            if (customButtons == null)
            {
                if (Message.CustomButtons != null && Message.CustomButtons.Length > 0)
                {
                    customButtons = new SimpleButton[Message.CustomButtons.Length];
                    int MaxButtonHeight = 0;
                    for (int i = 0; i < Message.CustomButtons.Length; i++)
                    {
                        //Create button
                        SimpleButton curButton = CreateButton(
                            Message.CustomButtons[i].Result,
                            Message.CustomButtons[i].Caption,
                            ref MaxButtonHeight);

                        if (curButton.DialogResult == System.Windows.Forms.DialogResult.Cancel)
                        {
                            this.CancelButton = curButton;
                        }

                        //Set the index in the tag
                        curButton.Click += new EventHandler(curButton_Click);
                        curButton.Tag = i;
                        if (Message.UseCommandLinks)
                        {
                            curButton.Appearance.TextOptions.HAlignment = HorzAlignment.Near;
                            curButton.ButtonStyle = BorderStyles.UltraFlat;
                            curButton.Appearance.BackColor = System.Drawing.Color.Transparent;
                            curButton.Appearance.Options.UseBackColor = true;
                            curButton.Appearance.Font = new Font(curButton.Appearance.Font.FontFamily, 12);
                        }
                        customButtons[i] = curButton;
                        this.Controls.Add(curButton);
                    }
                }
            }

            if (customButtons != null && Message.UseCommandLinks)
            {
                //Set the location and width of the command links
                foreach (SimpleButton sb in customButtons)
                {
                    sb.Width = MaxTextWidth;
                    sb.Location = new Point(TextLeft, FormTop);
                    FormTop += sb.Height;
                    BottomControlsHeight += sb.Height;
                }

                //Adjust formtop for footer panel
                FormTop += Spacing;
                BottomControlsHeight += Spacing;
            }

            //Footer adjustment
            FormTop += Spacing;
            BottomControlsHeight += Spacing;

            #endregion

            #region Footer controls created here

            //Create buttons
            if (!string.IsNullOrEmpty(Message.ExpandedInfo))
            {
                //Add the show/hide details button
                if (_ShowExpandedInfoButton == null)
                {
                    _ShowExpandedInfoButton = new SimpleButton();
                    _ShowExpandedInfoButton.LookAndFeel.Assign(LookAndFeel);
                    _ShowExpandedInfoButton.Text = _ShowExpandedInfoText[_ShowExpandedInfo];
                    _ShowExpandedInfoButton.Width = (_ShowExpandedInfoButton.CalcBestSize().Width > _ShowExpandedInfoButton.Width ?
                        _ShowExpandedInfoButton.CalcBestSize().Width : _ShowExpandedInfoButton.Width);
                    _ShowExpandedInfoButton.Click += new EventHandler(_ShowExpandedInfoButton_Click);
                    this.Controls.Add(_ShowExpandedInfoButton);
                }

                _ShowExpandedInfoButton.Location = new Point(Spacing, FormTop);
            }

            //Add the verification control if the verification text is set
            if (!string.IsNullOrEmpty(Message.VerificationText))
            {
                if (_VerificationControl == null)
                {
                    _VerificationControl = new CheckEdit();
                    _VerificationControl.LookAndFeel.Assign(LookAndFeel);
                    _VerificationControl.Text = Message.VerificationText;
                    _VerificationControl.Width = (_VerificationControl.CalcBestSize().Width > _VerificationControl.Width ?
                        _VerificationControl.CalcBestSize().Width : _VerificationControl.Width);
                    this.Controls.Add(_VerificationControl);
                }

                if (_ShowExpandedInfoButton != null)
                {
                    _VerificationControl.Location = new Point(Spacing, (_ShowExpandedInfoButton.Top + _ShowExpandedInfoButton.Height + Spacing));
                }
                else
                {
                    _VerificationControl.Location = new Point(Spacing, FormTop);
                }
            }

            //Create buttons
            if (buttons == null)
            {
                int maxButtonHeight = 0;
                if ((Message.Buttons == null || Message.Buttons.Length <= 0) &&
                    (Message.CustomButtons == null || Message.CustomButtons.Length <= 0))
                {
                    //When no buttons are specified, create a default OK button same as the TaskDialog
                    buttons = new SimpleButton[1];
                    SimpleButton OKButton = CreateButton(
                        DialogResult.OK,
                        GetButtonText(DialogResult.OK),
                        ref maxButtonHeight);
                    if (maxButtonHeight > 0)
                    {
                        OKButton.Height = maxButtonHeight;
                    }
                    buttons[0] = OKButton;
                    this.Controls.Add(OKButton);
                }
                else
                {
                    //Create the default buttons
                    buttons = new SimpleButton[Message.Buttons.Length];
                    for (int i = 0; i < buttons.Length; ++i)
                    {
                        SimpleButton currentButton = CreateButton(
                            Message.Buttons[i],
                            GetButtonText(Message.Buttons[i]),
                            ref maxButtonHeight);
                        buttons[i] = currentButton;

                        if (currentButton.DialogResult == DialogResult.None)
                            throw new ArgumentException("The 'DialogResult.None' button cannot be specified", "buttons");
                        if (currentButton.DialogResult == DialogResult.Cancel)
                            this.CancelButton = currentButton;

                        this.Controls.Add(currentButton);
                    }

                    if (maxButtonHeight > 0)
                    {
                        foreach (SimpleButton currentButton in buttons)
                        {
                            currentButton.Height = maxButtonHeight;
                        }
                    }
                }
            }

            if (this.CancelButton == null)
            {
                this.ControlBox = false;
            }

            //Set button location
            int nextButtonPos = FormWidth - Spacing - GetBordersSizes().Width;
            if (buttons != null)
            {
                for (int i = buttons.Length - 1; i >= 0; i--)
                {
                    nextButtonPos -= buttons[i].Width;
                    buttons[i].Location = new Point(nextButtonPos, FormTop);
                    nextButtonPos -= Spacing;
                }
            }

            if (customButtons != null && !Message.UseCommandLinks)
            {
                //Custom buttons as push buttons
                for (int i = customButtons.Length - 1; i >= 0; i--)
                {
                    nextButtonPos -= customButtons[i].Width;
                    customButtons[i].Location = new Point(nextButtonPos, FormTop);
                    nextButtonPos -= Spacing;
                }
            }

            //Adjust FormTop
            int ButtonHeight = 0;
            if (_ShowExpandedInfoButton != null && _VerificationControl != null)
            {
                //Adjust for both controls
                ButtonHeight = _ShowExpandedInfoButton.Height + Spacing + _VerificationControl.Height + Spacing;
                
            }
            else
            {
                //Just adjust with the button
                if (buttons != null)
                {
                    ButtonHeight = buttons[0].Height + Spacing;
                }
                else
                {
                    ButtonHeight = customButtons[0].Height + Spacing;
                }
            }

            FormTop += ButtonHeight;

            //Create footer icon rectangle
            if (Message.FooterIcon != null)
            {
                FormTop += Spacing;
                footerIconRectangle = new Rectangle(Spacing, FormTop, Message.FooterIcon.Width, Message.FooterIcon.Height);
            }
            else
            {
                footerIconRectangle = new Rectangle(Spacing, FormTop, 0, 0);
            }

            //Create footer text
            if (!string.IsNullOrEmpty(Message.FooterText) && footerControl == null)
            {
                int MaxFooterWidth = (FormWidth - (Spacing * 2) - GetBordersSizes().Width);
                if (Message.FooterIcon != null)
                {
                    MaxFooterWidth -= (footerIconRectangle.Width + Spacing);
                }
                footerControl = CreateLinkLabel(Message.FooterText, MaxFooterWidth);
                this.Controls.Add(footerControl);
            }

            if (footerControl != null)
            {
                if (Message.FooterIcon == null)
                {
                    //Only adjust FormTop if icon is null
                    FormTop += Spacing;
                }

                footerControl.Location = new Point(
                    (Message.FooterIcon == null ? Spacing :
                    (footerIconRectangle.Left + footerIconRectangle.Width + Spacing)), FormTop);
            }

            //Adjust formtop
            if (Message.FooterIcon != null || !string.IsNullOrEmpty(Message.FooterText))
            {
                int FooterHeight = 0;
                if (footerIconRectangle.Height > footerControl.Height)
                {
                    FooterHeight = footerIconRectangle.Height + Spacing;
                }
                else
                {
                    FooterHeight = footerControl.Height + Spacing;
                }
                FormTop += FooterHeight;
            }

            //Calculate the footer panel height
            PanelHeight = Spacing;
            if (_VerificationControl != null && _ShowExpandedInfoButton != null)
            {
                //Both controls visible, adjust height
                PanelHeight += _ShowExpandedInfoButton.Height + Spacing;
                PanelHeight += _VerificationControl.Height;
            }
            else
            {
                //Just use the button height
                PanelHeight += buttons[0].Height;
            }

            //Add Spacing
            PanelHeight += Spacing;

            //Add footer height
            if (Message.FooterIcon != null || !string.IsNullOrEmpty(Message.FooterText))
            {
                //FooterIcon or Text (or both) visible
                PanelHeight += Spacing;
                if (footerIconRectangle.Height > footerControl.Height)
                {
                    PanelHeight += footerIconRectangle.Height;
                }
                else
                {
                    PanelHeight += footerControl.Height;
                }
                PanelHeight += Spacing;
            }

            #endregion

            //Remove the scroll handlers
            xscTextControls.MouseEnter -= TextControls_MouseEnter;
            xscTextControls.MouseLeave -= TextControls_MouseLeave;
            content.MouseEnter -= TextControls_MouseEnter;
            content.MouseLeave -= TextControls_MouseLeave;
            if (expandedInfo != null)
            {
                expandedInfo.MouseEnter -= TextControls_MouseEnter;
                expandedInfo.MouseLeave -= TextControls_MouseLeave;
            }
            
            //Check the height
            if ((FormTop + GetBordersSizes().Height) > Screen.FromControl(this).WorkingArea.Height &&
                TextHeight == -1)
            {
                //Resize some items to fit everything
                //Calculate the textheight  
                int MaxTextHeight = Screen.FromControl(this).WorkingArea.Height -
                    (TopControlsHeight + BottomControlsHeight + PanelHeight + GetBordersSizes().Height);
                BuildTaskDialogForm(MaxTextHeight, IsFirstShown);
                
                //Enable mouse scrolling when the mouse enters the controls
                xscTextControls.MouseEnter += TextControls_MouseEnter;
                xscTextControls.MouseLeave += TextControls_MouseLeave;
                content.MouseEnter += TextControls_MouseEnter;
                content.MouseLeave += TextControls_MouseLeave;
                if (expandedInfo != null)
                {
                    expandedInfo.MouseEnter += TextControls_MouseEnter;
                    expandedInfo.MouseLeave += TextControls_MouseLeave;
                }

                ginfo.ReleaseGraphics();
                return;
            }

            //Set FormSize
            Size FormSize = new System.Drawing.Size(FormWidth, FormTop + GetBordersSizes().Height);
            this.MinimumSize = FormSize;
            this.MaximumSize = FormSize;

            //Center the form in the screen
            int FormLocationX = 0;
            int FormLocationY = 0;

            if (IsFirstShown)
            {
                if (Parent != null)
                {
                    FormLocationX = ((Screen.FromControl(Parent).WorkingArea.Width - FormSize.Width) / 2);
                    FormLocationY = ((Screen.FromControl(Parent).WorkingArea.Height - FormSize.Height) / 2);
                }
                else
                {
                    FormLocationX = ((Screen.FromControl(this).WorkingArea.Width - FormSize.Width) / 2);
                    FormLocationY = ((Screen.FromControl(this).WorkingArea.Height - FormSize.Height) / 2);
                }
            }
            else
            {
                //Perhaps the user moved the dialog, so just center vertically
                FormLocationX = this.Location.X;

                int ScreenHeight = 0;

                //Get the height of the screen we are on
                ScreenHeight = Screen.FromControl(this).WorkingArea.Height;

                //Check if we are bigger or equal to the height of the screen, if so just move to 
                //the top of the screen.
                if (FormSize.Height >= (ScreenHeight - Spacing))
                {
                    FormLocationY = 0;
                }
                else
                {
                    FormLocationY = this.Location.Y;
                }
            }

            //Update the location
            this.Location = new Point(FormLocationX, FormLocationY);

            if (IsFirstShown)
            {
                //Only set the focused button when first shown
                int FocusedButton = 0;
                if (Message.DefaultButtonIndex > -1 &&
                    Message.DefaultButtonIndex < buttons.Length)
                {
                    FocusedButton = Message.DefaultButtonIndex;
                }
                this.ActiveControl = buttons[FocusedButton];
                this.ActiveControl.Select();
            }

            ginfo.ReleaseGraphics();

        }

        void TextControls_MouseLeave(object sender, EventArgs e)
        {
            if (_PrevActiveControl != null)
            {
                this.ActiveControl = _PrevActiveControl;
                this.ActiveControl.Focus();
            }
        }

        void _ProgressBar_CustomDisplayText(object sender, CustomDisplayTextEventArgs e)
        {
            e.DisplayText = Message.CustomProgressBarText;
        }

        void TextControls_MouseEnter(object sender, EventArgs e)
        {
            if (this.ActiveControl != null)
            {
                _PrevActiveControl = this.ActiveControl;
            }
            xscTextControls.Focus();
        }

        void curButton_Click(object sender, EventArgs e)
        {
            selectedCustomButton = (int)((SimpleButton)sender).Tag;
        }

        private Rectangle GetTextRectangle(GraphicsInfo ginfo, string Text, Font Font, int left, int top, int maxTextWidth)
        {
            SizeF textSize = ginfo.Graphics.MeasureString(Text, Font, maxTextWidth);
            return new Rectangle(left, top, (int)Math.Ceiling(textSize.Width), (int)Math.Ceiling(textSize.Height));
        }

        private SimpleButton CreateButton(DialogResult result, string Caption, ref int maxButtonHeight)
        {
            SimpleButton currentButton = new SimpleButton();
            currentButton.LookAndFeel.Assign(LookAndFeel);
            currentButton.DialogResult = result;
            currentButton.Text = Caption;

            Size best = currentButton.CalcBestSize();
            if (best.Width > currentButton.Width)
                currentButton.Width = best.Width;
            if (best.Height > maxButtonHeight && best.Height > currentButton.Height)
                maxButtonHeight = best.Height;

            return currentButton;
        }

        public void SetProgressBarState(bool Enabled)
        {
            if (Message.Flags.HasFlag(XtraTaskDialogFlags.ShowMarqueeProgressBar))
            {
                ((MarqueeProgressBarControl)_ProgressBar).Properties.Stopped = !Enabled;
            }
        }

        private LinkLabelControl CreateLinkLabel(string Text, int MaxTextWidth)
        {
            LinkLabelControl llcLinkLabel = new LinkLabelControl();
            llcLinkLabel.AllowHtmlString = (Message.Flags.HasFlag(XtraTaskDialogFlags.EnableHyperlinks));
            llcLinkLabel.AutoSizeMode = LabelAutoSizeMode.Vertical;
            llcLinkLabel.Appearance.TextOptions.WordWrap = WordWrap.Wrap;
            llcLinkLabel.Width = MaxTextWidth;
            llcLinkLabel.Text = Text;
            
            Size llcSize = llcLinkLabel.GetPreferredSize(new Size(MaxTextWidth, 0));

            llcLinkLabel.Size = new Size(MaxTextWidth, llcSize.Height);

            if (Message.Flags.HasFlag(XtraTaskDialogFlags.EnableHyperlinks) &&
                Message.NotificationDelegate != null)
            {
                llcLinkLabel.LinkClicked += new LinkLabelControl.LinkClickedEventHandler(llcLinkLabel_LinkClicked);
            }

            return llcLinkLabel;
        }

        void llcLinkLabel_LinkClicked(object sender, LinkClickedEventArgs e)
        {
            if (Message.NotificationDelegate != null)
            {
                Message.NotificationDelegate(
                    this,
                    XtraTaskDialogNotificationType.HyperlinkClicked,
                    e.Link);
            }
        }

        public void SetProgressBarRange(int Minimum, int Maximum)
        {
            if (Minimum > Maximum)
            {
                throw new ArgumentException("Minimum value can't be greater than Maximum value.");
            }
            else if (Message.Flags.HasFlag(XtraTaskDialogFlags.ShowProgressBar))
            {
                ((ProgressBarControl)_ProgressBar).Properties.Minimum = Minimum;
                ((ProgressBarControl)_ProgressBar).Properties.Maximum = Maximum;
            }
        }

        public void CloseDialog(DialogResult TheResult)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new MethodInvoker(delegate()
                {
                    this.DialogResult = TheResult;
                    this.Close();
                }));
            }
            else
            {
                this.DialogResult = TheResult;
                this.Close();
            }
        }

        public void ControlCallbackTimer(bool IsCallbackTimerEnabled)
        {
            if (_CallbackTimer == null)
            {
                return;
            }

            if (IsCallbackTimerEnabled)
            {
                _CallbackTimer.Change(200, 200);
            }
            else
            {
                _CallbackTimer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
            }
        }
    }
}